home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / hardware / GIO_DRVR4.0.5 / gbd.c next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  11.2 KB  |  442 lines

  1. /*
  2.  * Copyright (C) 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  */
  5. #define _KERNEL /* more typically set on compile line */
  6.  
  7. #include <sys/param.h>
  8. #include <sys/systm.h>
  9. #include <sys/cpu.h>
  10. #include <sys/buf.h>
  11. #include <sys/user.h>
  12. #include <sys/cmn_err.h>
  13. #include <sys/edt.h>
  14.  
  15.     /* NOTE: this sample driver ignores the possiblity that
  16.      * the board might be busy handling some earlier request.
  17.      * any real device must deal with that possiblity, of course,
  18.      * before changing the board registers..
  19.      */
  20.  
  21. /* these defines and structures would normally be in a seperate
  22.  * header file */
  23.  
  24. #define GBD_BOARD_ID    0x75
  25. #define GBD_MASK    0xff    /* use 0xff if using only first byte 
  26.                  * of ID word, use 0xffff if using 
  27.                  * whole ID word
  28.                  */
  29.  
  30. #define  GBD_NUM_DMA_PGS  4    /* 0 for no hardware scatter/gather
  31.     * support, else number of pages of scatter/gather
  32.     * supported per request */
  33.  
  34. #define GBD_NODMA 0    /* non-zero for PIO version of driver */
  35.  
  36. #define GBD_MEMSIZE 0x8000
  37.  
  38. /* command definitions */
  39. #define GBD_GO 1
  40.  
  41. /* state definitions */
  42. #define GBD_SLEEPING 1
  43. #define GBD_DONE 2
  44.  
  45. /* direction of DMA definitions */
  46. #define GBD_READ 0
  47. #define GBD_WRITE 1
  48.  
  49. /* status defines */
  50. #define    GBD_INTR_PEND    0x80
  51.  
  52. /* "gbd" is device prefix; also in master.d/xxx file */
  53.  
  54. /* devices interface to the board */
  55. struct gbd_device {
  56.     int command;
  57.     int count;
  58.     int direction;
  59.     off_t offset;
  60.     unsigned *sgregisters; /* if scatter/gather supported */
  61.     caddr_t startaddr;    /* if no scatter/gather on board */
  62.     unsigned status;    /* errors, interrupt pending, etc. */
  63. };
  64.  
  65.  
  66. /* these are used for no scatter/gather case only, and assume
  67.  * (since they aren't protected!) that the driver is completely
  68.  * single threaded. */
  69. struct buf   *gbd_curbp[2];      /* current buffer */
  70. caddr_t      gbd_curaddr[2];    /* current address to transfer */
  71. int          gbd_curcount[2];
  72. int          gbd_totcount[2];
  73.  
  74. /* pointer to on-board registers */
  75. volatile struct gbd_device *gbd_device[2];
  76.  
  77. char *gbd_memory[2];   /* pointer to on-board memory */
  78.  
  79. static int gbd_state[2];   /* flag for transfer state 
  80.                 * (PIO driver) */
  81.  
  82. void gbdintr(int);
  83.  
  84. /* early device table initialization routine.  The edt
  85.  * structure is defined in edt.h.
  86.  */
  87. gbdedtinit(struct edt *e)
  88. {
  89.     int slot, val;
  90.  
  91.     /* Check to see if the device is present */
  92.     if(badaddr_val(e->e_base, sizeof(int), &val) || 
  93.             (val && GBD_MASK) != GBD_BOARD_ID) {
  94.         if (showconfig)
  95.             cmn_err (CE_CONT, 
  96.                 "gbdedtinit: board not installed.");
  97.             return;
  98.     }
  99.  
  100.  
  101.     /* figure out slot from base on VECTOR line in 
  102.      * system file */
  103.     if(e->e_base == 0xBF400000)
  104.         slot = GIO_SLOT_0;
  105.     else if(e->e_base == 0xBF600000)
  106.         slot = GIO_SLOT_1;
  107.     else {
  108.         cmn_err (CE_NOTE,
  109.         "ERROR from edtinit: Bad base address %x\n", e->e_base);
  110.         return;
  111.     }
  112.  
  113. #if IP12        /* for Indigo R3000, set up board as a 
  114.              * realtime bus master 
  115.              */
  116.  
  117.     setgioconfig(slot,0);
  118.  
  119. #endif
  120.  
  121. #if IP20         /* for Indigo R4000, set up board as a 
  122.              * realtime bus master 
  123.              */
  124.  
  125.     setgioconfig(slot,GIO64_ARB_EXP0_RT | GIO64_ARB_EXP0_MST);
  126.  
  127. #endif
  128.  
  129. #if IP22         /* for Indigo2, set up board as a pipelined,
  130.              * realtime bus master 
  131.              */
  132.  
  133.     setgioconfig(slot,GIO64_ARB_EXP0_RT | GIO64_ARB_EXP0_MST);
  134.  
  135. #endif
  136.  
  137.     /* Save the device addresses, because
  138.      * they won't be available later. */
  139.  
  140.     gbd_device[slot == GIO_SLOT_0 ? 0 : 1] = 
  141.                 (struct gbd_device *)e->e_base;
  142.     gbd_memory[slot == GIO_SLOT_0 ? 0 : 1] = 
  143.                 (char *)e->e_base2;
  144.     setgiovector(GIO_INTERRUPT_1,slot,gbdintr,0);
  145. }
  146.  
  147.  
  148. #ifdef GBD_NODMA
  149.  
  150. /* device write routine entry point (for character devices) */
  151. gbdwrite(dev_t dev)
  152. {
  153.     int unit = minor(dev)&1;
  154.     int size;
  155.     int s;
  156.  
  157.     while (u.u_count > 0) {
  158.         /* while there is data to transfer */
  159.  
  160.         /* Transfer no more than GBD_MEMSIZE bytes
  161.          * to the device */
  162.  
  163.         size = (u.u_count <
  164.             GBD_MEMSIZE ? u.u_count : GBD_MEMSIZE);
  165.  
  166.         /* decrements u.u_count while copying data */
  167.         iomove(gbd_memory[unit], size, B_WRITE);
  168.         if (u.u_error)
  169.             break;
  170.  
  171.         /* prevent interrupts until we sleep */
  172.         s = splgio1();
  173.  
  174.         /* Transfer is complete; start output */
  175.         gbd_device[unit]->count = u.u_count;
  176.         gbd_device[unit]->command = GBD_GO;
  177.         gbd_state[unit] = GBD_SLEEPING;
  178.         while (gbd_state[unit] != GBD_DONE) {
  179.             sleep(&gbd_state[unit], PRIBIO);
  180.         }
  181.         /* restore the process level after waking up */
  182.         splx(s);
  183.     }
  184. }
  185.  
  186.  
  187. /* interrupt routine for PIO only board, just wake up 
  188.  * upper half of driver
  189.  */
  190. void
  191. gbdintr(int unit)
  192. {
  193.     /* read your board's registers to determine if
  194.      * there are any errors or interrupts pending.
  195.      * If no interrupts are pending, return without
  196.      * doing anything.
  197.      */
  198.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  199.         return;
  200.  
  201.     if (gbd_state[unit] == GBD_SLEEPING) {
  202.         /* Output is complete; wake up top half
  203.          * of driver, if it is waiting */
  204.         gbd_state[unit] = GBD_DONE;
  205.         wakeup(&gbd_state[unit]);
  206.     }
  207.  
  208.     /* do anything else to board to tell it we are done
  209.      * with transfer and interrupt here */
  210. }
  211.  
  212. #else    /* DMA version of driver */
  213.  
  214. #if GBD_NUM_DMA_PGS > 0
  215.  
  216. /* block device read/write entry point, if your board has
  217.  * hardware scatter/gather DMA support.
  218.  */
  219. gbdstrategy(struct buf *bp)
  220. {
  221.     int unit = minor(bp->b_dev)&1;
  222.     int npages;
  223.     volatile unsigned *sgregisters;
  224.     int i, v_addr;
  225.  
  226.     /* Get address of the scatter-gather registers */
  227.      *sgregisters = gbd_device[unit]->sgregisters;
  228.  
  229.     /* Get the kernel virtual address of the data; note 
  230.      * b_dmaaddr may be NULL if the  BP_ISMAPPED(bp) macro 
  231.      * indicates false; in that case, the field bp->b_pages 
  232.      * is a pointer to a linked list of pfdat structure 
  233.      * pointers; that saves creating a virtual mapping and 
  234.      * then decoding that mapping back to physical addresses.  
  235.      * BP_ISMAPPED will never be false for character devices, 
  236.      * only block devices.
  237.      */
  238.      if(!BP_ISMAPPED(bp)) {
  239.         cmn_err(CE_WARN, 
  240.             "gbd driver can't handle unmapped buffers");
  241.         bp->b_flags |= B_ERROR;
  242.         iodone(bp);
  243.         return;
  244.     }
  245.  
  246.     v_addr = bp->b_dmaaddr;
  247.  
  248.     /* Compute number of pages received.
  249.      * The dma_len field provides the number of pages to
  250.      * map. Note that this may be larger than the actual
  251.      * number of bytes involved in the transfer. This is
  252.      * because the transfer may cross page boundaries,
  253.      * requiring an extra page to be mapped.  Limit to
  254.      * number of scatter/gather registers on board.
  255.      * Note that this sample driver doesn't handle the
  256.      * case of requests > than # of registers!
  257.      */
  258.     npages = numpages (v_addr, bp->b_dmalen);
  259.     /*
  260.      * Provide the beginning byte offset and count to the
  261.      * device.
  262.      */
  263.     gbd_device[unit]->offset = 
  264.             (unsigned int)bp->b_dmaaddr & (NBPC-1);
  265.     if(npages > GBD_NUM_DMA_PGS) {
  266.          npages = GBD_NUM_DMA_PGS;
  267.         cmn_err(CE_WARN, 
  268.             "request too large, only %d pages max", npages);
  269.         if(gbd_device[unit]->offset)
  270.             gbd_device[unit]->count = NBPC - 
  271.                 gbd_device[unit]->offset + (npages-1)*NBPC;
  272.         else
  273.             gbd_device[unit]->count = npages*NBPC;
  274.         bp->b_resid = bp->b_count - gbd_device[unit]->count;
  275.     }
  276.     else
  277.         gbd_device[unit]->count = bp->b_count;
  278.  
  279.     /* Translate the virtual address of each page to a
  280.      * physical page number and load it into the next
  281.      * scatter-gather register.  The btoct(K) macro
  282.      * converts the byte value to a page value after
  283.      * rounding down the byte value to a full page.
  284.      */
  285.      for (i = 0; i < npages; i++) {
  286.         *sgregisters++ = btoct(kvtophys(v_addr));
  287.  
  288.         /*
  289.         /* Get the next virtual address to translate.
  290.          * (NBPC is a symbolic constant for the page
  291.          * size in bytes)
  292.          */
  293.  
  294.         v_addr += NBPC;
  295.     }
  296.  
  297.     if ((bp->b_flags & B_READ) == 0)
  298.         gbd_device[unit]->direction = GBD_WRITE;
  299.     else
  300.         gbd_device[unit]->direction = GBD_READ;
  301.     gbd_device[unit]->command = GBD_GO;    /* start DMA */
  302.  
  303.     /* and return; upper layers of kernel wait for iodone(bp) */
  304. }
  305.  
  306.  
  307. /* not much to do in this interrupt routine, since we are 
  308.  * assuming for this driver that we can never have to do 
  309.  * multiple DMA's to handle the number of bytes requested...
  310.  */
  311. void
  312. gbdintr(int unit)
  313. {
  314.     int error;
  315.  
  316.     /* read your board's registers to determine if
  317.      * there are any errors or interrupts pending.
  318.      * If no interrupts are pending, return without
  319.      * doing anything.
  320.      */
  321.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  322.         return;
  323.  
  324.     if(error)
  325.         bp->b_flags |= B_ERROR;
  326.      
  327.     iodone(bp);    /* we are done, tell upper layers */
  328.  
  329.     /* do anything else to board to tell it we are done
  330.      * with transfer and interrupt here */
  331. }
  332.  
  333. #else /*  GBD_NUM_DMA_PGS == 0; no hardware 
  334.        *  scatter/gather support */
  335.  
  336. gbdstrategy(struct buf *bp)
  337. {
  338.     int unit = minor(bp->b_dev)&1;
  339.  
  340.     /* any checking for initial state here. */
  341.  
  342.     /* Get the kernel virtual address of the data; note 
  343.      * b_dmaaddr may be NULL if the  BP_ISMAPPED(bp) macro 
  344.      * indicates false; in that case, the field bp->b_pages 
  345.      * is a pointer to a linked list of pfdat structure 
  346.      * pointers; that saves creating a virtual mapping and 
  347.      * then decoding that mapping back to physical addresses.  
  348.      * BP_ISMAPPED will never be false for character devices, 
  349.      * only block devices.
  350.      */
  351.      if(!BP_ISMAPPED(bp)) {
  352.         cmn_err(CE_WARN, 
  353.             "gbd driver can't handle unmapped buffers");
  354.         bp->b_flags |= B_ERROR;
  355.         iodone(bp);
  356.         return;
  357.     }
  358.  
  359.     gbd_curbp[unit] = bp;
  360.     /*
  361.      * Initialize the current transfer address and count.
  362.      * The first transfer should finish the rest of the
  363.      * page, but do no more than the total byte count.
  364.      */
  365.     gbd_curaddr[unit] = bp->b_dmaaddr;
  366.     gbd_totcount[unit] = bp->b_count;
  367.     gbd_curcount[unit] = NBPC -
  368.         ((unsigned int)gbd_curaddr[unit] & (NBPC-1));
  369.     if (bp->b_count < gbd_curcount[unit])
  370.         gbd_curcount[unit] = bp->b_count;
  371.     /* Tell the device starting physical address, count,
  372.      * and direction */
  373.     gbd_device[unit]->startaddr = kvtophys(gbd_curaddr[unit]);
  374.     gbd_device[unit]->count = gbd_curcount[unit];
  375.     if (bp->b_flags & B_READ) == 0)
  376.         gbd_device[unit]->direction = GBD_WRITE;
  377.     else
  378.         gbd_device[unit]->direction = GBD_READ;
  379.     gbd_device[unit]->command = GBD_GO;    /* start DMA */
  380.  
  381.     /* and return; upper layers of kernel wait for iodone(bp) */
  382. }
  383.  
  384.  
  385. /* more complicated interrupt routine, not necessarily because
  386.  * board has DMA, but more typical of boards that do have
  387.  * DMA, since they are typically more complicated.
  388.  * Also more typical of devices that support block i/o, as 
  389.  * opposed to character i/o.
  390.  */
  391. void
  392. gbdintr(int unit)
  393. {
  394.     int error;
  395.     register struct buf *bp = gbd_curbp[unit];
  396.  
  397.     /* read your board's registers to determine if
  398.      * there are any errors or interrupts pending.
  399.      * If no interrupts are pending, return without
  400.      * doing anything.
  401.      */
  402.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  403.         return;
  404.  
  405.     if(error) {
  406.         bp->b_flags |= B_ERROR;
  407.         iodone(bp);    /* we are done, tell upper layers */
  408.     }
  409.     else {
  410.         /* On successful transfer of last chunk, continue
  411.          * if necessary */
  412.         gbd_curaddr[unit] += gbd_curcount[unit];
  413.         gbd_totcount[unit] -= gbd_curcount[unit];
  414.         if(gbd_totcount[unit] <= 0)
  415.             iodone(bp);    
  416.                 /* we are done, tell upper layers */
  417.         else {
  418.         /* else more to do, reprogram board and 
  419.          * start next dma */
  420.         gbd_curcount[unit] =
  421.             (gbd_totcount[unit] < NBPC 
  422.                     ? gbd_totcount[unit] : NBPC);
  423.         gbd_device[unit]->startaddr = 
  424.                     kvtophys(gbd_curaddr[unit]);
  425.         gbd_device[unit]->count = gbd_curcount[unit];
  426.         if (bp->b_flags & B_READ) == 0)
  427.             gbd_device[unit]->direction = GBD_WRITE;
  428.         else
  429.             gbd_device[unit]->direction = GBD_READ;
  430.         gbd_device[unit]->command = GBD_GO;    
  431.                     /* start next DMA */
  432.         }
  433.     }
  434.  
  435.     /* do anything else to board to tell it we are done
  436.      * with transfer and interrupt here */
  437. }
  438. #endif /*  GBD_NUM_DMA_PGS */
  439.  
  440. #endif /* GBD_NODMA */
  441.  
  442.